<template>
  <div>
    <div class="container">
      <TableCustom
        :columns="columns"
        :table-data="menuData"
        row-key="id"
        :has-pagination="false"
        :view-func="handleView"
        :del-func="handleDelete"
        :edit-func="handleEdit"
      >
        <template #toolbarBtn>
          <el-button type="warning" :icon="CirclePlusFilled" @click="handleAdd">新增</el-button>
        </template>
        <template #icon="{ row }">
          <el-icon>
            <component :is="row.icon"></component>
          </el-icon>
        </template>
      </TableCustom>
    </div>
    <el-dialog
      v-model="visible"
      :title="isEdit ? '编辑' : '新增'"
      width="700px"
      destroy-on-close
      :close-on-click-modal="false"
      @close="closeDialog"
    >
      <TableEdit
        :form-data="rowData"
        label-width="100px"
        :span="12"
        :columns="editColumns"
        :edit="isEdit"
        :update="updateData"
      >
        <template #parent="{ row }">
          <el-cascader v-model="row.pid" :options="menuData" :props="cascaderProps" clearable />
        </template>
      </TableEdit>
    </el-dialog>
    <el-dialog v-model="viewVisible" title="查看详情" width="700px" destroy-on-close>
      <TableDetail :row="viewRow" :columns="viewColumns">
        <template #icon="{ rows }">
          <el-icon>
            <component :is="rows.icon"></component>
          </el-icon>
        </template>
      </TableDetail>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
  import { ref } from 'vue'
  import { ElMessage } from 'element-plus'
  import { CirclePlusFilled } from '@element-plus/icons-vue'
  import { remove, saveOrUpdate } from '@/api/menu.ts'
  import { Menu, MenuSaveOrUpdateParam } from '@/types'
  import TableCustom from '@/components/common/TableCustom.vue'
  import TableDetail from '@/components/common/TableDetail.vue'
  import TableEdit from '@/components/common/TableEdit.vue'
  import { menuTreeList } from '@/api/menu.ts'

  const menuData = ref<Menu[]>([])

  const cascaderProps = ref({
    checkStrictly: true, //严格的遵守父子节点不互相关联
    label: 'title',
    value: 'id',
    emitPath: false, //返回单个值
  })
  //获取列表数据

  const getData = async () => {
    menuData.value = await menuTreeList({})
  }
  getData()

  // 表格配置
  let columns = ref([
    { prop: 'title', label: '菜单名称', align: 'left' },
    { prop: 'icon', label: '图标' },
    { prop: 'path', label: '路由路径' },
    { prop: 'sort', label: '排序' },
    { prop: 'operator', label: '操作', width: 250 },
  ])

  // 新增/编辑弹窗配置
  const editColumns = ref([
    { type: 'input', label: '菜单名称', prop: 'title', required: true },
    { type: 'input', label: '路由路径', prop: 'path', required: true },
    { type: 'input', label: '图标', prop: 'icon' },
    { type: 'number', label: '排序', prop: 'sort' },
    { type: 'parent', label: '父菜单', prop: 'pid' },
  ])

  //显示新增修改弹窗
  const visible = ref(false)
  //是否编辑
  const isEdit = ref(false)
  //操作数据
  const rowData = ref({})
  //新增
  const handleAdd = () => {
    rowData.value = {}
    isEdit.value = false
    visible.value = true
  }
  //编辑
  const handleEdit = (row: Menu) => {
    rowData.value = { ...row }
    isEdit.value = true
    visible.value = true
  }
  //更新数据
  const updateData = async (data: MenuSaveOrUpdateParam) => {
    await saveOrUpdate(data)
    ElMessage.success('保存成功')
    closeDialog()
    await getData()
  }
  //关闭弹窗
  const closeDialog = () => {
    visible.value = false
    isEdit.value = false
  }

  // 查看详情弹窗相关
  const viewVisible = ref(false)
  //查看数据
  const viewRow = ref({})
  //查看的配置
  const viewColumns = ref([
    { prop: 'id', label: '菜单ID' },
    { prop: 'pid', label: '父菜单ID' },
    { prop: 'title', label: '菜单名称' },
    { prop: 'path', label: '路由路径' },
    { prop: 'sort', label: '排序' },
    { prop: 'icon', label: '图标' },
  ])
  //查看
  const handleView = (row: Menu) => {
    viewRow.value = { ...row }
    viewVisible.value = true
  }

  // 删除
  const handleDelete = async (row: Menu) => {
    await remove({ id: row.id })
    ElMessage.success('删除成功')
    await getData()
  }
</script>

<style scoped></style>
